package com.example.demo.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.apache.commons.codec.digest.DigestUtils;

import java.util.Map;
import java.util.TreeMap;

public class TestMd5UnSign extends BaseMd5 {

    public static final String APPID = "appId";
    public static final String SIGN = "sign";
    public static final String CHANNELTYPE = "channelType";
    public static final String TIMESTAMP = "timestamp";
    public static final String METHOD = "method";
    public static final String DATA = "data";



    /**
     * 校验签名 gson
     * @param req
     * @return
     */
    public static boolean checkSignGson(String req){
        System.out.println("---------------------");
        System.out.println(req);
        System.out.println("---------------------");
        return  getWaitingSignStringByGson(req);
    }
    /**
     * 校验签名 fastJson
     * @param req
     * @return
     */
    public static boolean checkSignFastJson(String req){
        System.out.println("---------------------");
        System.out.println(req);
        System.out.println("---------------------");
        return  getWaitingSignStringByFastJson(req);
    }


    /**
     * 校验签名 jackson
     * @param req
     * @return
     */
    public static boolean checkSignJackson(String req) throws JsonProcessingException {
        System.out.println("---------------------");
        System.out.println(req);
        System.out.println("---------------------");
        return  getWaitingSignStringByJackson(req);
    }

    public static boolean getWaitingSignStringByFastJson(String json){
        String key =  BaseMd5.appKey + BaseMd5.appSecret;
        JSONObject reqJsonObj = JSON.parseObject(json);
        String signReq = reqJsonObj.get(SIGN).toString();
        String appId = reqJsonObj.get(APPID).toString();
        String channelType = reqJsonObj.get(CHANNELTYPE).toString();
        String timeStamp = reqJsonObj.get(TIMESTAMP).toString();
        String method = reqJsonObj.get(METHOD).toString();
        System.out.println("请求签名串："+signReq);
        String data = reqJsonObj.get(DATA).toString();
        TreeMap<String,Object> dataTreeMap = JSON.parseObject(data, TreeMap.class,Feature.OrderedField);


        StringBuffer sb = new StringBuffer(key);
        sb.append(appId);
        //将channelType放入公共参数，校验时增加接入渠道
        sb.append(channelType);
        StringBuffer dataWaitSignStr = new StringBuffer();
        for(Map.Entry<String,Object> entry : dataTreeMap.entrySet()){
            dataWaitSignStr.append(entry.getValue());
        }
        sb.append(dataWaitSignStr);
        sb.append(method);
        sb.append(timeStamp);

        System.out.println("fastJson待签名串："+sb.toString());
        String signStr = DigestUtils.md5Hex(sb.toString());
        System.out.println("fastJson生成的签名串:"+signStr);
        boolean result = signStr.toUpperCase().equals(signReq);
        System.out.println("fastJson校验结果："+result);
        return result;
    }

    public static boolean getWaitingSignStringByGson(String json){
        String key =  BaseMd5.appKey + BaseMd5.appSecret;
        Gson gson = new Gson();
        JsonObject gsonObj = gson.fromJson(json,JsonObject.class);
        String signReq = gsonObj.get(SIGN).getAsString();
        String appId = gsonObj.get(APPID).getAsString();
        String channelType = gsonObj.get(CHANNELTYPE).getAsString();
        long timeStamp = gsonObj.get(TIMESTAMP).getAsLong();
        String method = gsonObj.get(METHOD).getAsString();
        System.out.println("请求签名串："+signReq);
        String data = gsonObj.get(DATA).toString();
        TreeMap<String,Object> treeMap = gson.fromJson(data,TreeMap.class);

        StringBuffer sb = new StringBuffer(key);
        sb.append(appId);
        //将channelType放入公共参数，校验时增加接入渠道
        sb.append(channelType);

        for(Map.Entry<String,Object> entry : treeMap.entrySet()){
            sb.append(entry.getValue());
        }
        sb.append(method);
        sb.append(timeStamp);
        System.out.println("GSON待签名串："+sb.toString());
        String signStr = DigestUtils.md5Hex(sb.toString());
        System.out.println("GSON生成的签名串:"+signStr);
        boolean result = signStr.toUpperCase().equals(signReq);
        System.out.println("GSON校验结果："+result);
        return result;
    }


    public static boolean getWaitingSignStringByJackson(String json) throws JsonProcessingException {
        String key =  BaseMd5.appKey + BaseMd5.appSecret;
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode objWrapper = mapper.readValue(json, ObjectNode.class);
        String signReq = objWrapper.get(SIGN).asText();
        String appId = objWrapper.get(APPID).asText();
        String channelType = objWrapper.get(CHANNELTYPE).asText();
        long timeStamp = objWrapper.get(TIMESTAMP).asLong();
        String method = objWrapper.get(METHOD).asText();
        System.out.println("请求签名串："+signReq);
        String data = objWrapper.get(DATA).toString();
        TreeMap<String,Object> treeMap = mapper.readValue(data,TreeMap.class);

        StringBuffer sb = new StringBuffer(key);
        sb.append(appId);
        //将channelType放入公共参数，校验时增加接入渠道
        sb.append(channelType);

        for(Map.Entry<String,Object> entry : treeMap.entrySet()){
            sb.append(entry.getValue());
        }
        sb.append(method);
        sb.append(timeStamp);
        System.out.println("Jackson待签名串："+sb.toString());
        String signStr = DigestUtils.md5Hex(sb.toString());
        System.out.println("Jackson生成的签名串:"+signStr);
        boolean result = signStr.toUpperCase().equals(signReq);
        System.out.println("Jackson校验结果："+result);
        return result;
    }
}
